/*************************************************************************
* Title:    2WIRE serial Interface to TWI Serial EEPROM Devices
* Author:   Brent C. Reamer (BrentBXR @ AVRFreaks Forum)
* File:     $id twi_eeprom TWI.Library BrentBXR
* Software: AVR-GCC 3.4.3 / avr-libc 1.2.3
* Target:   any AVR device with hardware TWI
* Need:		Pete Fluery's TWIMaster.c Library
* Usage:    API compatible with I2C Software Library i2cmaster.h by Pete Fluery
*			To use a custom TWI runner create compat define's
**************************************************************************/

#include <inttypes.h>
#include <avr/io.h>
#include <compat/twi.h>

#include "twimaster.h"
#include "twi_eeprom.h"


/**
 @brief Writes one (1) byte to the specified device @ the specified address

 @param   uint8_t	wDeviceAddr: Device address
 @param   uint8_t	wByte: The byte to write to the device
 @param   uint16_t	wAddr: Location address to store byte in EEPROM memory
 @retval  int		:1 = Write OK / 0 = Write FAIL
 */
unsigned int eeprom_wr_byte(uint8_t wDeviceAddr, uint8_t wByte, uint16_t wAddr)
{
	uint8_t RetVal = 1;
	if (TWBR)
	{
		wDeviceAddr &= ~(1<<0);		//Set R/W bit to Write (0);
		i2c_start_wait(wDeviceAddr);	//Start TWI bus activity and send Address to Drive, wait until device ACK
		i2c_write((wAddr >> 8));		//Sent write Address high bits first
		i2c_write(wAddr);				//Send write address low bits section
		RetVal = i2c_write(wByte);		//Write the single bit.
		i2c_stop();
	}
	else
	{
		RetVal = 1; 					//TWI NOT READY
	}

	return((RetVal) ? 0 : 1);
}


/**
 @brief Writes a string to the specified device @ the specified address

 @param   uint8_t	wDeviceAddr: Device address
 @param   uint8_t	*s: String to write
 @param   uint16_t	wAddr: Location address to store byte in EEPROM memory
 @retval  int		:1 = Write OK / 0 = Write FAIL
 */
unsigned int eeprom_wr_string(uint8_t wDeviceAddr,const char *s, uint16_t wAddr)
{
	uint8_t RetVal = 1;
    while (*s)
	{
		RetVal = eeprom_wr_byte(wDeviceAddr,*s++,wAddr);
		wAddr++;
		if(RetVal == 0)
			break;
	}
	return RetVal;
}


/**
 @brief Reads one (1) byte from specified device @ specified memory address

 @param   uint8_t	wDeviceAddr: Device address
 @param   uint16_t	wAddr: Location address to store byte in EEPROM memory
 @retval  int		: the byte
 */
unsigned int eeprom_rd_byte(uint8_t wDeviceAddr, uint16_t wAddr)
{
	uint8_t RetVal;
	if (TWBR)
	{
		wDeviceAddr &= ~(1<<0);		//Set R/W bit to Write (0);
		i2c_start_wait(wDeviceAddr);	//Start TWI bus activity and send Address to Drive, wait until device ACK
		i2c_write((wAddr >> 8));		//Sent write Address high bits first
		i2c_write(wAddr);				//Send write address low bits section
		wDeviceAddr |= (1<<0);			//Set R/W bit to Read (1);
		i2c_start_wait(wDeviceAddr);	//Start TWI bus activity and send Address to Drive, wait until device ACK
		RetVal = i2c_readNak();			//Write the single bit.
		i2c_stop();
	}
	else
	{
		RetVal = 0; 					//TWI NOT READY
										//The problem with this is that you cant depend on this being 0 and it being an error as
										//0x00 might be saved at the address'd location. But it is still good to have here because
										//with Pete's library if you try to use a read or write function and TWI is not initiated then
										//the program freezes on 'i2c_start_wait'.
	}

	return RetVal;
}
